package com.rpay.service.user.impl;

import com.rpay.common.dto.user.UserVerifyDTO;
import com.rpay.common.enums.PcsResultCode;
import com.rpay.common.exception.UserException;
import com.rpay.common.util.LoggerUtil;
import com.rpay.common.util.http.HttpUtil;
import com.rpay.common.util.http.exception.HttpProcessException;
import com.rpay.common.util.http.request.HttpConfig;
import com.rpay.dao.user.UserDao;
import com.rpay.dao.user.UserVerifyDao;
import com.rpay.model.user.UserDO;
import com.rpay.model.user.UserVerifyDO;
import com.rpay.service.config.ServiceThreadLocal;
import com.rpay.service.user.IUserVerifyService;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Title：
 * Description
 *
 * @author fxg06 on 2018/5/3
 * @version 1.0
 */
@Service
public class UserVerifyServiceImpl implements IUserVerifyService {
    @Value("${juhe.ocr.url}")
    private String ocrUrl;
    @Value("${juhe.ocr.key}")
    private String ocrKey;
    @Value("${juhe.verify.url}")
    private String verifyUrl;
    @Value("${juhe.verify.key}")
    private String verifyKey;

    @Autowired
    private UserVerifyDao userVerifyDao;
    @Autowired
    private UserDao userDao;

    @Override
    @Transactional
    public UserVerifyDTO ocr(String image, String side) {
        String str = null;
        try {
            str = post(side, image);
        } catch (Exception e) {
            throw new UserException(PcsResultCode.USER_VERIFY_FAIL);
        }

        JSONObject json = new JSONObject(str);
        //扫描身份证正面且返回数据等于0，识别成功，去实名认证
        if (json.getInt("error_code") == 0 && "front".equals(side)) {
            JSONObject result = json.getJSONObject("result");
            UserVerifyDO userVerifyDO = convertJsonTODTO(result);
//            UserVerifyDTO userVerifyDTO = verify(userVerifyDO.getRealname(), userVerifyDO.getIdcard());
            //不为null 表示身份认证成功，插入数据，更新用户数据
//            if (userVerifyDTO != null) {
//                userVerifyDao.insert(userVerifyDO);
                UserDO userDO = new UserDO();
                userDO.setId(userVerifyDO.getUserId());
                userDO.setName(userVerifyDO.getRealname());
                userDO.setIdcard(userVerifyDO.getIdcard());
                userDao.update(userDO);
                return convertDOToDTO(userVerifyDO);
//            } else {
//                throw new UserException(PcsResultCode.USER_VERIFY_FAIL);
//            }
        } else {
            throw new UserException(PcsResultCode.USER_VERIFY_FAIL);
        }
    }

    @Override
    public UserVerifyDTO verify(String name, String idcard) {
        HttpConfig httpConfig = HttpConfig.custom().param("key", verifyKey)
                .param("realname", name)
                .param("idcard", idcard);
        try {
            String str = HttpUtil.post(httpConfig.url(verifyUrl));
            JSONObject jsonObject = new JSONObject(str);
            if (jsonObject.getInt("error_code") == 0) {
                JSONObject result = jsonObject.getJSONObject("result");
                if (result.getInt("res") == 1) {
                    UserVerifyDTO userVerifyDTO = new UserVerifyDTO();
                    userVerifyDTO.setRealname(name);
                    userVerifyDTO.setIdcard(idcard);
                    return userVerifyDTO;
                }
            }
        } catch (HttpProcessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private UserVerifyDO convertJsonTODTO(JSONObject jsonObject) {
        UserVerifyDO userVerify = new UserVerifyDO();
        userVerify.setUserId(ServiceThreadLocal.getUserId());
        userVerify.setAddress(jsonObject.getString("address"));
        userVerify.setBorn(jsonObject.getString("born"));
        userVerify.setIdcard(jsonObject.getString("idcard"));
        userVerify.setNation(jsonObject.getString("nation"));
        userVerify.setRealname(jsonObject.getString("realname"));
        userVerify.setSex(jsonObject.getString("sex"));
        return userVerify;
    }

    private UserVerifyDTO convertDOToDTO(UserVerifyDO userVerifyDO) {
        UserVerifyDTO userVerify = null;
        if (userVerifyDO != null) {
            userVerify = new UserVerifyDTO();
            userVerify.setId(userVerifyDO.getId());
            userVerify.setAddress(userVerifyDO.getAddress());
            userVerify.setBorn(userVerifyDO.getBorn());
            userVerify.setIdcard(userVerifyDO.getIdcard());
            userVerify.setNation(userVerifyDO.getNation());
            userVerify.setRealname(userVerifyDO.getRealname());
            userVerify.setSex(userVerifyDO.getSex());
            userVerify.setUserId(userVerifyDO.getUserId());
        }
        return userVerify;
    }

    public String post(String side, String image) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String result = null;
        // HttpClient请求的相关设置，可以不用配置，用默认的参数，这里设置连接和超时时长(毫秒)
        RequestConfig config = RequestConfig.custom().setConnectTimeout(30000).setSocketTimeout(30000).build();
        try {
            HttpPost httppost = new HttpPost(ocrUrl);
            // StringBody封装String类型的参数
            StringBody keyBody = new StringBody(ocrKey, ContentType.TEXT_PLAIN);
            StringBody sideBody = new StringBody(side, ContentType.TEXT_PLAIN);
            StringBody imageBody = new StringBody(image, ContentType.TEXT_PLAIN);
            // addPart将参数传入，并指定参数名称
            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("image", imageBody).addPart("key", keyBody)
                    .addPart("side", sideBody).build();
            httppost.setEntity(reqEntity);
            httppost.setConfig(config);
            // 执行网络请求并返回结果
            response = httpClient.execute(httppost);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                result = ConvertStreamToString(resEntity.getContent(), "UTF-8");
            }
            EntityUtils.consume(resEntity);
        } finally {
            response.close();
            httpClient.close();
        }
        // 得到的是JSON类型的数据需要第三方解析JSON的jar包来解析
        return result;
    }
    
    public static String ConvertStreamToString(InputStream is, String charset)
            throws Exception {
        StringBuilder sb = new StringBuilder();
        try (InputStreamReader inputStreamReader = new InputStreamReader(is,charset)) {
            try (BufferedReader reader = new BufferedReader(inputStreamReader)) {
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\r\n");
                }
            }
        }
        return sb.toString();
    }
}
